﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace ARchGL.Platform.Utils
{
    /// <summary>
    /// 
    /// </summary>
    public static class ConvertHelper
    {
        /// <summary>
        /// 两个相似实体转换
        /// </summary>
        /// <typeparam name="S">源实体</typeparam>
        /// <typeparam name="T">赋值实体</typeparam>
        /// <param name="source">源实体值</param>
        /// <returns></returns>
        public static T Map<S, T>(this S source) where T : new()
        {
            if (source == null) return default(T);

            var propertiesT = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public);
            var propertiesL = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);

            var entity = new T();
            foreach (PropertyInfo itemL in propertiesL)
            {
                foreach (PropertyInfo itemT in propertiesT)
                {
                    if (itemL.Name != itemT.Name || itemL.PropertyType != itemT.PropertyType) continue;

                    var value = itemT.GetValue(source, null);

                    itemL.SetValue(entity, value, null);
                    break;
                }
            }
            return entity;
        }

        /// <summary>
        /// 克隆一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static T Clone<T>(this T source)
        {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("The type must be serializable.", "source");
            }

            // Don't serialize a null object, simply return the default for that object
            if (ReferenceEquals(source, null))
            {
                return default(T);
            }

            var formatter = new BinaryFormatter();
            var stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }

        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        /// <param name="httpContextAccessor"></param>
        /// <returns></returns>
        public static string GetClientIpAddress(this IHttpContextAccessor httpContextAccessor)
        {
            var address = httpContextAccessor.HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            if (string.IsNullOrEmpty(address))
                address = httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();

            //var address = httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();

            address = address == "::1" || address == "0.0.0.1"
                ? "127.0.0.1"
                : address;

            return address.Contains(',')
                ? address.Split(',')[0]
                : address;
        }
    }
}
